using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.IO;

public class ABAtlasTools : EditorWindow
{
    private string folderPath= "";
    private string outFolder = "ExportPrefab";
    private string outPath = "";
    private bool atlasSplitState = true;
    private bool exportPrefabState = false;

    [MenuItem("AssetBundle工具/解析Atlas AB")]
    static void CreateWin()
    {
        EditorWindow.GetWindow(typeof(ABAtlasTools));
    }
    ABAtlasTools()
    {
        titleContent = new GUIContent("解析ab包图集资源");
        maxSize = new Vector2(300,400);
        minSize = new Vector2(300,400);
    }
    private void OnEnable()
    {
        // outPath = Application.dataPath+"/"+outFolder;
        // folderPath = Application.dataPath;
        folderPath = PlayerPrefs.GetString("ABAtlasTools_ABPath", "");
        outPath = PlayerPrefs.GetString("ABAtlasTools_outPath", "");
    }
    private void OnGUI()
    {
        // if (GUILayout.Button("选择图集ab包的目录", GUILayout.Width(200)))
        // {
        //     string _tempPath = EditorUtility.OpenFolderPanel("选择路径:", Application.dataPath, "");
        //     if (string.IsNullOrEmpty(_tempPath))
        //     {
        //         EditorUtility.DisplayDialog("错误", "请选择目录", "OK");
        //         return;
        //     }
        //     folderPath = _tempPath;
        // }
        GUILayout.Label("AB路径:", GUILayout.Width(200));
        folderPath = GUILayout.TextArea(folderPath);
        GUILayout.Label("导出路径:", GUILayout.Width(200));
        outPath = GUILayout.TextArea(outPath);
        // EditorGUILayout.LabelField("导出路径:Assets/"+outFolder);
        GUILayout.Space(10);
        atlasSplitState = EditorGUILayout.Foldout(atlasSplitState, "从ab拆分图集小图", true);
        if (atlasSplitState)
        {
            if (GUILayout.Button("拆分图集小图", GUILayout.Width(200)))
            {
                PlayerPrefs.SetString("ABAtlasTools_ABPath", folderPath);
                PlayerPrefs.SetString("ABAtlasTools_outPath", outPath);
                AssetBundle.UnloadAllAssetBundles(false);
                string[] files = Directory.GetFiles(folderPath);
                for (int i = 0; i < files.Length; i++)
                {
                    string path = files[i];
                    EditorUtility.DisplayProgressBar("", $"执行：{i}/{files.Length}" , i/files.Length);
                    if (path.Contains("."))
                        continue;
                    ExportTexturePNGFromAtlas(path);
                }
                Debug.LogError("图集导出完成!");
                AssetBundle.UnloadAllAssetBundles(false);
               
            }
        }
        GUILayout.Space(50);
        exportPrefabState = EditorGUILayout.Foldout(exportPrefabState, "从ab导出prefab", true);
        if (exportPrefabState)
        {
            if (GUILayout.Button("导出图集prafab图集", GUILayout.Width(200)))
            {
                AssetBundle.UnloadAllAssetBundles(false);
                string[] files = Directory.GetFiles(folderPath);
                for (int i = 0; i < files.Length; i++)
                {
                    string path = files[i];
                    EditorUtility.DisplayProgressBar("", $"执行：{i}/{files.Length}" , i/files.Length);
                    if (path.Contains("."))
                        continue;
                    ExportAtlasAssetsFromAB(path);
                }
                Debug.LogError("prefab导出完成!");
                AssetBundle.UnloadAllAssetBundles(false);
                PlayerPrefs.SetString("ABAtlasTools_ABPath", folderPath);
                PlayerPrefs.SetString("ABAtlasTools_outPath", outPath);
            }
        }


        EditorUtility.ClearProgressBar();
    }
    public void ExportAtlasAssetsFromAB(string path)
    {
        AssetBundle ab = AssetBundle.LoadFromFile(path);
        if (ab == null)
        {
            Debug.LogError(path+"：ab包不存在");
            return;
        }
        System.Object[] objs = ab.LoadAllAssets();
        GameObject go;
        for (int i = 0; i < objs.Length; i++)
        {
            go = objs[i] as GameObject;
            Debug.Log(objs[i].GetType());
            if (go)
            {
                UIAtlas atlas = go.GetComponent<UIAtlas>();
                if (atlas)
                {
                    if (atlas.spriteMaterial)
                    {   
                        Shader shader = Shader.Find(atlas.spriteMaterial.shader.name);
                        string matPath = string.Format("Assets\\{0}\\{1}.mat", outFolder, atlas.spriteMaterial.name);
                        if (File.Exists(matPath))
                            File.Delete(matPath);

                        // if (shader == null)
                        {
                            shader = Shader.Find("Unlit/Transparent Colored");
                        }
                        Material mats = new Material(shader);
                        AssetDatabase.CreateAsset(mats, matPath);
                        Texture mainTexture = atlas.spriteMaterial.GetTexture("_MainTex");
                        if (mainTexture != null)
                        {
                            SaveTextureToPNG(mainTexture, Application.dataPath +"/"+ outFolder, atlas.spriteMaterial.name);
                            mats.SetTexture("_MainTex", mainTexture);
                        }
                        Texture alphaTexture = atlas.spriteMaterial.GetTexture("_AlphaTex");
                        if (alphaTexture != null)
                        {
                            SaveTextureToPNG(alphaTexture, Application.dataPath +"/"+ outFolder, atlas.spriteMaterial.name+"_Alpha");
                            mats.SetTexture("_AlphaTex", alphaTexture);
                        }
                        GameObject gos = new GameObject(go.name);
                        UIAtlas at = gos.AddComponent<UIAtlas>();
                        at.spriteMaterial = mats;
                        at.spriteList = atlas.spriteList;
                        at.MarkAsChanged();
                        PrefabUtility.SaveAsPrefabAsset(gos, string.Format("Assets\\{0}\\{1}.prefab", outFolder, go.name));
                        AssetDatabase.SaveAssets();
                        AssetDatabase.Refresh();
                    }
                }
            }
        }
       
        // ab.Unload(false);
    }
    public void ExportTexturePNGFromAtlas(string path)
    {
        UIAtlas atlas = null;
        AssetBundle ab = AssetBundle.LoadFromFile(path);

        if (ab == null)
        {
            Debug.LogError(path+"：ab包不存在");
            return;
        }
        Debug.LogError(path+"：解析");
        // ab.getp
        System.Object[] objs = ab.LoadAllAssets();
        GameObject go;
        for (int i = 0; i < objs.Length; i++)
        {
            if(objs[i].GetType() == typeof(Texture2D) )
            {   
                Texture2D texture =objs[i] as Texture2D;
                SaveTextureToPNG(texture, outPath, texture.name, texture.format);
                continue;
            }
            go = objs[i] as GameObject;
            if (!go)
                Debug.LogError(path+"：ab包没有图集和单图");
            else
            {
                atlas = go.GetComponent<UIAtlas>();
                if (atlas && atlas.spriteMaterial)
                {
                    // ExportTexturePNGFromAtlas(outPath + "/" + atlas.name,atlas);
                    // continue;
                    List<UISpriteData> exitSpritesList = atlas.spriteList;
                    Texture2D atlasTexture = atlas.spriteMaterial.GetTexture("_MainTex") as Texture2D;
                    if(atlasTexture == null)
                        break;
                    atlasTexture = GetTexture2D(atlasTexture, atlasTexture.format);
                    int oldwith = atlasTexture.width;
                    int oldHeight = atlasTexture.height;
                    Color32[] oldPixels = null;
                    foreach (var es in exitSpritesList)
                    {
                        int xmin = Mathf.Clamp(es.x, 0, oldwith);
                        int ymin = Mathf.Clamp(es.y, 0, oldHeight);
                        int newWidth = Mathf.Clamp(es.width, 0, oldwith);
                        int newHeight = Mathf.Clamp(es.height, 0, oldHeight);
                        if (newWidth == 0 || newHeight == 0) continue;
                        if (oldPixels == null) oldPixels = atlasTexture.GetPixels32();
                        int width = newWidth + es.paddingLeft + es.paddingRight;
                        int height = newHeight + es.paddingTop + es.paddingBottom;
                        Color32[] newPixels = new Color32[width * height];
                        for (int p = 0; p < newPixels.Length; p++)
                        {
                            newPixels[p] = new Color32(0, 0, 0, 0);
                        }
                        for (int y = 0; y < newHeight; ++y)
                        {
                            for (int x = 0; x < newWidth; ++x)
                            {
                                int newIndex = (height - 1 - (es.paddingTop+y)) * width + x + es.paddingLeft;
                                int oldIndex = (oldHeight - 1 - (ymin + y)) * oldwith + (xmin + x);
                                newPixels[newIndex] = oldPixels[oldIndex];
                            }
                        }
                        Texture2D t = new Texture2D(width, height);
                        t.SetPixels32(newPixels);
                        t.Apply();
                        byte[] bytes = t.EncodeToPNG();
                        t = null;
                        if (!Directory.Exists(outPath + "/" + atlas.name))
                            Directory.CreateDirectory(outPath + "/" + atlas.name);
                        if (File.Exists(outPath + "/" + atlas.name + "/" + es.name + ".png"))
                            File.Delete(outPath + "/" + atlas.name + "/" + es.name + ".png");
                        using (FileStream fs = new FileStream(outPath + "/" + atlas.name +"/" + es.name + ".png", FileMode.CreateNew))
                        {
                            BinaryWriter writer = new BinaryWriter(fs);
                            writer.Write(bytes);
                        }
                    }
                }
            }
        }
        // ab.Unload(false);
    }
    public Texture2D SaveTextureToPNG(Texture inputTex, string contents, string pngName, TextureFormat format = TextureFormat.ARGB32)
	{
        Texture2D png = GetTexture2D(inputTex, format);
        SaveTextureToFile(png, contents, pngName);
        Texture2D.DestroyImmediate(png);
        return png;
	} 
    public void SaveTextureToFile(Texture2D png,string contents, string pngName)
    {
		if (!Directory.Exists(contents))
			Directory.CreateDirectory(contents);
        
        // if (png.format == TextureFormat.RGB24)
        // {
        //     byte[] bytes = png.EncodeToJPG();
        //     FileStream file = File.Open(contents + "/" + pngName + ".jpg", FileMode.Create);
        //     BinaryWriter writer = new BinaryWriter(file);
        //     writer.Write(bytes);
        //     file.Close();
        // }
        // else
        // {
            byte[] bytes = png.EncodeToPNG();
            FileStream file = File.Open(contents + "/" + pngName + ".png", FileMode.Create);
            BinaryWriter writer = new BinaryWriter(file);
            writer.Write(bytes);
            file.Close();

        // }
        

    }
    public Texture2D GetTexture2D(Texture inputTex, TextureFormat format = TextureFormat.ARGB32)
    {
        RenderTexture temp = RenderTexture.GetTemporary(inputTex.width, inputTex.height, 0, RenderTextureFormat.ARGB32);
		Graphics.Blit(inputTex, temp);
		RenderTexture.active = temp;
		Texture2D png = new Texture2D(temp.width, temp.height, TextureFormat.ARGB32, false);
        png.ReadPixels(new Rect(0, 0, temp.width, temp.height), 0, 0);
        return png;
    }


}
